package com.xiaoqiudong.pojo.game;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaoqiudong.GobangApplication;
import com.xiaoqiudong.mapper.UserInfoMapper;
import com.xiaoqiudong.pojo.User;
import com.xiaoqiudong.pojo.request.GameRequest;
import com.xiaoqiudong.pojo.response.GameResponse;
import jdk.swing.interop.SwingInterOpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA
 * Descroption
 * User:dell
 * Date:2025-08-16
 * Time:15:39
 */
public class Room {
    private String roomId;
    private User user1;
    private User user2;

    private int whiteUser;
//    @Autowired
    private OnlineUserManager onlineUserManager;

//    @Autowired
    private RoomManager roomManager;

    private UserInfoMapper userMapper;

    private ObjectMapper objectMapper = new ObjectMapper();
    // 这个二维数组用来表示棋盘
    // 约定:
    // 1) 使用 0 表示当前位置未落子. 初始化好的 int 二维数组, 就相当于是 全 0
    // 2) 使用 1 表示 user1 的落子位置
    // 3) 使用 2 表示 user2 的落子位置
    private static final int MAX_ROW = 15;
    private static final int MAX_COL = 15;
    private int[][] board = new int[MAX_ROW][MAX_COL];

    public void putChess(String requestString) throws IOException {
        //记录落子位置
        GameRequest gameRequest = objectMapper.readValue(requestString,GameRequest.class);
        GameResponse gameResponse = new GameResponse();
        //根据当前用户的id潘多落子是玩家1，还是玩家2，判定是1还是2
        int chess = gameRequest.getUserId() == user1.getUserId() ? 1:2;
        int row = gameRequest.getRow();
        int col = gameRequest.getCol();
        if (board[row][col] != 0){
            //重复落子判定
            System.out.println("当前位置（"+row+","+col+")已经有子了");
            return;
        }
        board[row][col] = chess;
        //打印棋盘信息
        printBoard();

        //胜负判定
        int winner = checkWinner(row,col,chess);

        //给房间中的所有客户端返回响应
        gameResponse.setMessage("putChess");
        gameResponse.setUserId(gameRequest.getUserId());
        gameResponse.setCol(col);
        gameResponse.setRow(row);
        gameResponse.setWinner(winner);
        // 要想给用户发送 websocket 数据, 就需要获取到这个用户的 WebSocketSession
        WebSocketSession session1 = onlineUserManager.getFromGameRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getFromGameRoom(user2.getUserId());
        //查看用户是否掉线
        if(session1 == null){
            //玩家1下线，玩家2获胜
            System.out.println("玩家1掉线");
            gameResponse.setWinner(user2.getUserId());
        }
        if (session2 == null){
            //玩家2掉线，玩家1获胜
            System.out.println("玩家2掉线");
            gameResponse.setWinner(user1.getUserId());
        }
        String respJsonString = objectMapper.writeValueAsString(gameResponse);
        if (session1 != null){
            session1.sendMessage(new TextMessage(respJsonString));
        }
        if (session2 != null){
            session2.sendMessage(new TextMessage(respJsonString));
        }


        //如果胜负已分，销毁房间（将房间从房间管理器移除）
        if (gameResponse.getWinner() != 0){
            //胜负已分
            System.out.println("游戏结束！房间即将销毁 roomId="+roomId+"获胜方:"+gameResponse.getWinner());
            int winUserId = gameResponse.getWinner();
            int loseUserId = gameResponse.getWinner() == user1.getUserId() ? user2.getUserId(): user1.getUserId();
            userMapper.userWin(winUserId);
            userMapper.userLose(loseUserId);
            roomManager.remove(roomId,user1.getUserId(),user2.getUserId());
        }
    }

    private int checkWinner(int row, int col, int chess) {

        //检查所有行
        for (int c = col-4; c <=col ; c++) {
            try{
                if(board[row][c] == chess
                        && board[row][c+1] == chess
                        && board[row][c+2] == chess
                        && board[row][c+3] == chess
                        && board[row][c+4] == chess){
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        //检查所有列
        for (int r = row - 4 ; r <=row ; r++) {
            try{
                if(board[r][col] == chess
                        && board[r+1][col] == chess
                        && board[r+2][col] == chess
                        && board[r+3][col] == chess
                        && board[r+4][col] == chess){
                    return chess == 1 ? user1.getUserId():user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }

        //检测左对角线

        for (int r = row - 4, c = col - 4; r <= row && c <= col; r++, c++) {
            try {
                if (board[r][c] == chess
                        && board[r + 1][c + 1] == chess
                        && board[r + 2][c + 2] == chess
                        && board[r + 3][c + 3] == chess
                        && board[r + 4][c + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }

        }
        //检查右对角线
        for (int r = row-4,c = col+4 ; r<=row && c>=col;r++,c--){
            try{
                if (board[r][c] == chess
                    && board[r+1][c-1] == chess
                    && board[r+2][c-2] == chess
                    && board[r+3][c-2] == chess
                    && board[r+4][c-4] == chess){
                    return chess == 1 ? user1.getUserId():user2.getUserId();
                }
            }catch (ArrayIndexOutOfBoundsException e){
                continue;
            }
        }
        return 0;
    }

    private void printBoard() {
        //打印棋盘信息
        System.out.println("[答应棋盘信息]");
        System.out.println("======================");
        for (int row = 0; row < MAX_ROW; row++) {
            for (int col = 0; col < MAX_COL; col++) {
                System.out.print(board[row][col]+" ");
            }
            System.out.println();
        }
        System.out.println("======================");

    }

    public int getWhiteUser() {
        return whiteUser;
    }

    public void setWhiteUser(int whiteUser) {
        this.whiteUser = whiteUser;
    }


    public Room(){
        //构造room的时候，生产唯一的标识 uuid
        roomId = UUID.randomUUID().toString();
        //通过入口类中记录的 context 手动获取RoomManager 和 OnlineUserManager
        onlineUserManager = GobangApplication.context.getBean(OnlineUserManager.class);
        roomManager = GobangApplication.context.getBean(RoomManager.class);
        userMapper = GobangApplication.context.getBean(UserInfoMapper.class);
    }

    public void setRoomId(String roomId) {
        this.roomId = roomId;
    }

    public void setUser1(User user1) {
        this.user1 = user1;
    }

    public void setUser2(User user2) {
        this.user2 = user2;
    }

    public String getRoomId() {
        return roomId;
    }

    public User getUser1() {
        return user1;
    }

    public User getUser2() {
        return user2;
    }
}
